const myarr = [1, 2, 3];

type myArrKeyof = keyof [1, 2, 3]; // 要是为数组这里面的东西可多, 这里面的值为 1 | 2 | 3 | length| 以及数据原型上的所有东西;

type objKeyOf = keyof object; // never

interface TestInterface {
  [props: number]: string;
}

interface TestStr {
  [prop: string]: string;
}

type mmInn = keyof TestInterface;

type myStr = keyof TestStr; // number | string ; 因为ey 可以为string也可以为number

const obj: mmInn = 123;

console.log(obj);

const str: myStr = 123;

console.log(str);

const sstr: myStr = "kklhelloMMMMlkk";

console.log(sstr);

// keyof 的用途

/**
 * 比如写个函数：
 * function(obj, key) {
 *  return obj[key];
 * }
 * 我们希望使用的 obj 的返回类型只能是any, key 只能是obj的key，那怎么处理呢
 */

/**这个是什么样的呢
 *
 * this i s a
 * @param obj object对象
 * @param key  object 的key值
 */
export function MyFunc<Obj extends Object, K extends keyof Obj>(
  obj: Obj,
  key: K,
): Obj[K] {
  return obj[key];
}

export const UserObj0 = {
  name: "myObj",
  age: 18,
  getName() {
    return UserObj0.name;
  },
};

export function test() {
  return "hello word";
}

const myName = MyFunc(UserObj0, "name");

const getName = MyFunc(UserObj0, "getName");

// const mg = MyFunc(UserObj0, "age");

// console.log(mg);

console.log(getName());

console.log(myName, "demo");

// 把一个对象的所有属性性统一成一种类型
type TestObj<T extends object> = {
  [key in keyof T]: boolean;
};

const UserObj = {
  name: "zhgsna",
  age: 19,
  isMerry: false,
};
type objType = typeof UserObj0;

type myobj = TestObj<typeof UserObj0>; // 此时就把所有key转成了 boolean 类型

// 把一个对象中的可选属性以及readonly属性干掉
type TypeTest2 = {
  name: string;
  age?: number;
  readonly hibbit?: boolean;
};

// -？ 就是把去掉可选的属性
type MMTypeTestAllType<T extends object> = {
  -readonly [K in keyof T]-?: T[K];
};

type AllUserType = MMTypeTestAllType<TypeTest2>;

const myObj3: AllUserType = {
  name: "zhgsna",
  age: 40, // 这个是必须要的，否则报错
  hibbit: false,
};

myObj3.hibbit = true;
console.log(myObj3);

const myObj4: TypeTest2 = {
  name: "zhgsna",
  hibbit: false,
};

console.log(myObj4);
console.log(123);

// 下面就报错
// myObj4.hibbit = true;

// console.log(myObj4);
//
//
const dom = document.getElementById("mmm");

console.log(dom);

const MyFunc3 = () => {
  const myfunc = MyFunc(
    {
      a: 123,
      b: "ssfd",
      c: {
        mmm: 44,
      },
    },
    "a",
  );

  myfunc.valueOf();
};

const myfuncmm = MyFunc(
  {
    a: 123,
    b: "ssfd",
    c: {
      mmm: 44,
    },
  },
  "c",
);

myfuncmm.mmm;

const myfu = MyFunc(
  {
    a: 123,
    b: "ssfd",
    c: {
      mmm: 44,
    },
  },
  "b",
);

myfu.charAt(1);
